package com.sec.etech.ism.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sec.etech.ism.model.IsmAppSetting;
import com.sec.etech.ism.model.IsmServiceDef;
import com.sec.etech.ism.service.*;
import com.sec.etech.ism.util.SapSignatureUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.openbpm.base.core.util.StringUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class IsmSendSapComponentBomImpl implements IsmMethodService {

    @Resource
    IsmCommonService ismCommonService;
    @Resource
    IsmAppSettingService ismAppSettingService;
    @Resource
    IsmServiceDefService ismServiceDefService;
    @Resource
    IsmTaskService ismTaskService;
    @Resource
    IsmTaskLogService ismTaskLogService;

    @Override
    public JSONObject call(String sysCode, String serviceCode, JSONObject businessParams) throws Exception {
        JSONObject result = new JSONObject();
        String msg = this.sendSapComponentBom(sysCode, serviceCode, businessParams);
        result.put("flag", msg);
        result.put("msg", msg);
        return result;
    }

    @Override
    public String methodName() {
        return "sendSapComponentBom";
    }

    /**
     * 封装请求参数
     *
     * @param componentid
     * @param componentIds
     * @return
     */
    private JSONObject getSapComponentBom(Long componentid, String componentIds) {
        JSONObject jsonObject = ismCommonService.sendComponentBom(componentid, componentIds);

        JSONArray bomList = jsonObject.getJSONArray("bomList");
        String headers = "MATNR\tWERKS\tSTLAN\tDATUV\tBMENG\tPOSNR\tSORTF\tPOSTP\tIDNRK\tZTEXT\tMENGE\tMEINS\tSANFE\tPOTX1\tPOTX2\n" +
                "父物料编号\t工厂\tBOM 用途\tBOM有效起始日期\t父件基本数量\t项目序号\t排序字符串\t项目类别\t组件物料号\t组件描述\t组件数量\t组件单位\t生产相关\t项目文本1\t项目文本2\n" +
                "Material\tPlant\tBOM Usage\tValid From\tBase quantity\tItem Number\tSort String\tItem Category\tComponent\tComponent Description\tQuantity\tBase Unit of Measure\tproduction relevant\tItem Text Line 1\tItem Text Line 2";

        List<JSONObject> list = new ArrayList<>();
        int row = 1;
        for (String ss : headers.split("\n")) {
            int cow = 1;
            for (String s : ss.split("\t")) {
                JSONObject obj = new JSONObject();
                obj.put("ROW", String.valueOf(row));
                obj.put("COL", String.valueOf(cow));
                obj.put("VALUE", s);
                list.add(obj);
                cow++;
            }
            row++;
        }

        for (Object o : bomList) {
            JSONArray objects = JSONArray.parseArray(JSONArray.toJSONString(o));
            for (Object ob : objects) {
                JSONObject obj = JSONObject.parseObject(JSONObject.toJSONString(ob));
                if (obj.get("amount")==null || obj.getDouble("amount") == 0) {
                    continue;
                }
                String[] cellArr = new String[13];
                //BOM父级物料号
                cellArr[0] = obj.getString("parentMaterialNo");
                cellArr[1] = "1303";//默认1303
                cellArr[2] = "1";//默认1
                cellArr[3] = "2008-12-31";//默认2008-12-31
                cellArr[4] = "1";//默认1
                cellArr[5] = obj.getString("index");
                cellArr[6] = obj.getString("orderNum");
                cellArr[7] = obj.getString("drawingFlag");
                if ("L".equals(obj.getString("drawingFlag"))) {
                    cellArr[8] = obj.getString("materialNo");
                } else {
                    if (StrUtil.isBlank(obj.getString("partsNum"))) {
                        cellArr[9] = obj.getString("partsNum");
                    } else {
                        cellArr[9] = obj.getString("partsNum") + " " + obj.getString("partsName");
                    }
                }
                cellArr[10] = obj.getString("amount");
                /*if ("T".equals(obj.getString("drawingFlag"))) {
                    cellArr[11] = "ST";
                } else if (obj.getInteger("detaillist") != null && obj.getInteger("detaillist").equals(1)) {
                    cellArr[11] = "套";
                } else if ("KG".equals(obj.getString("meins"))) {
                    cellArr[11] = "KG";
                } else {
                    cellArr[11] = "EA";
                }*/
                cellArr[12] = "X";
                for (int i = 0; i < cellArr.length; i++) {
                    JSONObject cellobj = new JSONObject();
                    cellobj.put("ROW", String.valueOf(row));
                    cellobj.put("COL", String.valueOf(i + 1));
                    cellobj.put("VALUE", StrUtil.isNotBlank(cellArr[i]) ? cellArr[i] : "");
                    list.add(cellobj);
                }
                row++;
            }
        }

        JSONObject sap_params = new JSONObject();
        sap_params.put("I_FLG_MESSAGE_DISPLAY", "");
        sap_params.put("T_INTERN", list);
        return sap_params;
    }

    /**
     * 发送部套BOM的JSON结构到SAP
     *
     * @param sysCode
     * @param serviceCode
     * @param busObj
     * @return
     */
    private String sendSapComponentBom(String sysCode, String serviceCode, JSONObject busObj) {

        Map<String, String> logMap = new HashMap<>(5);
        //服务信息
        IsmServiceDef serviceDef = null;
        try {
            serviceDef = ismServiceDefService.getByCode(serviceCode);
            //调用的应用信息
            IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);

            String url = ismCommonService.getSapPreUrl(appSetting.getAppAddress(), appSetting.getAppConfig()) + "/ZBAPI_PLM_UPLOAD_BOM";

            JSONObject params = getSapComponentBom(busObj.getLong("componentid"), busObj.getString("componentids"));

            JSONObject dataObj = this.checkSapResult(url, params, serviceDef, appSetting.getAppKey2(),
                    null, busObj.toJSONString(), sysCode, "ZBAPI_PLM_UPLOAD_BOM", logMap);
            if (dataObj == null) {
                return "发送部套BOM的JSON结构到SAP接口异常，请联系管理员处理！";
            } else if (StringUtil.isEmpty(dataObj.getString("message"))) {
                return "success";
            } else {
                return dataObj.getString("message");
            }
        } catch (Exception e) {
            log.error("发送部套BOM的JSON结构到SAP接口异常。serviceDef.getCode()={}，serviceDef.getName()={}，logMap={}",
                    serviceDef.getCode(), serviceDef.getName(), logMap);
            e.printStackTrace();
            return "发送部套BOM的JSON结构到SAP接口异常，请联系管理员处理！";
        }
    }


    //检查sap返回结果，获取返回数据
    private JSONObject checkSapResult(String url, JSONObject sapParams, IsmServiceDef serviceDef, String appKey, String businessCode,
                                      String businessParams, String sysCode, String methodName, Map<String, String> logMap) throws Exception {

        JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
        String body = JSONObject.toJSONString(bodyObj);
        int timeout = JSONObject.parseObject(serviceDef.getParams()).getInteger("timeout");
        String result = HttpUtil.post(url, body, timeout * 60 * 1000);
        JSONObject resultObj = JSONObject.parseObject(result);

        JSONObject taskObj = new JSONObject();
        taskObj.put("sysCode", sysCode);
        taskObj.put("serviceCode", serviceDef.getCode());
        taskObj.put("methodName", methodName);
        taskObj.put("businessCode", businessCode);
        taskObj.put("businessParams", businessParams);
        taskObj.put("resultObj", resultObj);
        Long taskId = ismTaskService.checkAndSave(taskObj);
        //保存接口调用日志
        JSONObject logObj = new JSONObject();
        logObj.put("task_id", taskId);
        logObj.put("service_code", serviceDef.getCode());
        logObj.put("service_name", serviceDef.getName());
        logObj.put("method_name", methodName);
        logObj.put("request_url", url);
        logObj.put("input_json", bodyObj);
        logObj.put("output_json", result);
        JSONObject dataObj = resultObj != null ? resultObj.getJSONObject("data") : null;
        String message = null;
        if (resultObj == null || !resultObj.getBoolean("success")) {
            message = resultObj != null ? resultObj.getString("message") : "接口无返回数据，请检查接口和网络！";
        } else if (dataObj != null && StringUtil.isNotEmpty(dataObj.getString("RETURN"))) {
            message = dataObj.getJSONObject("RETURN").getString("MESSAGE");
        } else if (dataObj != null && StringUtil.isNotEmpty(dataObj.getString("RET"))) {
            message = dataObj.getJSONObject("RET").getString("MESSAGE");
        } else if (dataObj != null && StringUtil.isNotEmpty(dataObj.getString("T_RETURN"))) {
            JSONArray tReturn = dataObj.getJSONArray("T_RETURN");
            //默认成功的，只有报错信息的才认为是失败的
            boolean success = true;
            for (Object o : tReturn) {
                JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(o));
                String DYNAME = MapUtils.getString(jsonObject, "DYNAME", "");
                String MSGV3 = MapUtils.getString(jsonObject, "MSGV3", "");
                String MSGV4 = MapUtils.getString(jsonObject, "MSGV4", "");
                message = "";
                if ("下列需要导入的BOM数据有错误".equals(DYNAME) && !DYNAME.equals(MSGV3) && !"提示信息".equals(MSGV4)) {
                    message = StrUtil.format("{}\n{}\n", MSGV3, MSGV4);
                    success = false;
                } else if ("SAP系统物料及BOM检查情况".equals(DYNAME) && !DYNAME.equals(MSGV3) && !"提示信息".equals(MSGV4)) {
                    //只有失败的的才认为是失败
                    if (MSGV4.indexOf("失败") > -1) {
                        message = StrUtil.format("{}\n{}\n", MSGV3, MSGV4);
                        success = false;
                    }
                }
            }
            //失败的存task表，没有失败的只存log表
            if (!success) {
                taskId = ismTaskService.saveOrUpdateTask(sysCode, serviceDef.getCode(), methodName, businessCode, businessParams, null);
                logObj.put("task_id", taskId);
            }
        }

        logObj.put("message", message);
        logMap.put("input", body);
        logMap.put("output", result);
        ismTaskLogService.saveLog(logObj);
        if (dataObj != null) {
            dataObj.put("message", message);
        }
        return dataObj;
    }

}
